package com.bblocks.common.anti_reptile.rule;

import com.bblocks.common.anti_reptile.config.AntiReptileProperties;
import com.bblocks.common.anti_reptile.config.bean.RuleComm;
import com.bblocks.common.anti_reptile.config.bean.RuleResultParams;
import com.bblocks.common.anti_reptile.config.bean.UserRule;
import com.bblocks.common.anti_reptile.constant.RuleResultEnum;
import com.bblocks.common.anti_reptile.module.MatchResult;
import com.bblocks.common.anti_reptile.module.RuleVO;
import com.bblocks.common.anti_reptile.service.TokenService;
import lombok.extern.slf4j.Slf4j;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author Jin
 * @since 2024/3/23 14:40
 */
@Slf4j
public abstract class AbstractRule implements AntiReptileRule {


    @Override
    public MatchResult match(HttpServletRequest request, HttpServletResponse response) {
        return doMatch(request,response);
    }

    /**
     * 执行
     * @param request
     * @param response
     * @return 存在则符合规则-部分规则可能允许后修执行
     */
    protected abstract MatchResult doMatch(HttpServletRequest request, HttpServletResponse response);


    protected String userId(HttpServletRequest request, RuleComm userRule, TokenService tokenService){
        if(userRule.getTokenKey() == null || userRule.getTokenKey().isEmpty())
            return null;
        String token = request.getHeader(userRule.getTokenKey());
        if(token == null || token.isEmpty()){
            return null;
        }

        String userId =  tokenService.token2UserId(request,token);
        if(userId == null || userId.isEmpty()){//非登录状态
            return null;
        }else
            return userId;
    }


    /**
     * 返回ruleComm，根据ruleVO（有可能返回特制的规则）
     * 条件：仅当 ruleVo 返回特制规则
     * @param properties
     * @param ruleResult 匹配结果的规则
     * @param ruleVO 规则属性
     * @param id ip/userId/AntiReptileConsts.PLATE_NAME
     * @param url 涉嫌资源
     * @return
     */
    protected MatchResult matchResult(AntiReptileProperties properties, RuleComm ruleResult, RuleVO ruleVO,String id,String url){
        return matchResultWithResultEnum(properties,  ruleResult,  ruleVO!= null && ruleVO.getRuleResultEnum() != null ? ruleVO.getRuleResultEnum() : null, id, url);
    }

    protected MatchResult matchResultWithResultEnum(AntiReptileProperties properties, RuleComm ruleResult, RuleResultEnum toRuleResultEnum, String id, String url){
        RuleComm matchRule = null;
        if(toRuleResultEnum == null || toRuleResultEnum.getLockType().equals(ruleResult.getLockType()))
            matchRule = ruleResult;
        else{
            RuleResultParams theRuleResultParams = null;
            if(properties.getRuleResultParams() != null && !properties.getRuleResultParams().isEmpty()){
                theRuleResultParams = properties.getRuleResultParams()
                        .stream()
                        .filter(p->p.getLockType().equals(toRuleResultEnum.getLockType()))
                        .findFirst()
                        .orElse(null);
            }
            if (theRuleResultParams != null ){
                RuleComm ruleCommNew = RuleComm.cloneOne(ruleResult);;

                ruleCommNew.setLockType(theRuleResultParams.getLockType());
                ruleCommNew.setLockExpire(theRuleResultParams.getLockExpire());
                ruleCommNew.setLockResponse(theRuleResultParams.getLockResponse());
                matchRule = ruleCommNew;
            }else{
                log.warn("规则：{} 未配置响应类型：{} 处理结果，缺失参数：{} ",ruleResult.getRuleTypeEnum().getDesc(),toRuleResultEnum.getLockType(),"anti.reptile.rule-result-params");
                matchRule = ruleResult;
            }
        }
        return MatchResult.builder()
                .matchRule(matchRule)
                .id(id)
                .url(url)
                .build();
    }
}
